/*
 * lexer.h
 *
 *  Created on: Nov 11, 2010
 *      Author: cpy.prefers.you@gmail.com
 */
#ifndef LEXER_H_
#define LEXER_H_

#include "headers.h"

#define IS_WHITE(chr)        (chr == ' ' || chr == TAB || chr == LF)
#define IS_ALPHA(chr)        ((chr >= 'A' && chr <= 'Z') || (chr >= 'a' && chr <= 'z'))
#define IS_IDENTIFIER_PREFIX(chr)   (IS_ALPHA(chr) || chr == '_')

#define IS_DECIMAL(chr)      (chr >= '0' && chr <= '9')
#define IS_HEX(chr)          (chr >= '0' && chr <= '9' || chr >= 'a' && chr <= 'f' || chr >= 'A' && chr <= 'F')
#define IS_OCT(chr)          (chr >= '0' && chr <= '7')

#define IS_ALNUM(chr)        (IS_ALPHA(chr) || IS_DECIMAL(chr))

#define IS_SINGLE_QUOTATION_MARK(chr) (chr == '\'')
#define IS_DOUBLE_QUOTATION_MARK(chr) (chr == '\"')

#define IS_BACKSLASH(chr)    (chr == '\\')

#define IS_OP(chr) (\
                    chr == '+' || chr == '-' || chr == '*' || chr == '/' || chr == '%' || \
                    chr == '=' || chr == '!' || chr == '|' || chr == '&' || chr == '^' || \
                    chr == '>' || chr == '<' || chr == '~' || chr == ',' || chr == '.' || \
                    chr == '[' || chr == ']' || chr == '(' || chr == ')' \
                    )

#define MESSAGE_LEN            0x7f
#define TOKEN_LEN              0x1f
#define STRING_LEN             0xffff
#define KEYWORD_NUM            0x21
#define INPUT_BUFFER_SIZE      0xffffff
#define INPUT_READ_SIZE        0x7fff
#define INPUT_CACHE_SIZE       0xffff

#define TAB '\x0B'
#define LF  '\x0A'

enum ListOfKeywordTypes
{
    KEYWORD_OTHERS,
    KEYWORD_STORAGE_CLASS,
    KEYWORD_MODIFIER_LEN,
    KEYWORD_MODIFIER_SIGN,
    KEYWORD_QUALIFIER,
    KEYWORD_DATA_TYPE,
    KEYWORD_CONTROL_CONSTRUCT,
    KEYWORD_RETURN,
    KEYWORD_STRUCT,
    KEYWORD_UNION,
    NUMBER_OF_KEYWORD_TYPES
};

enum ListOfTokenTypes
{
    TYPE_UNKNOWN,
    TYPE_KEYWORD,
    TYPE_IDENTIFIER,
    TYPE_NUMBER,
    TYPE_CHAR,
    TYPE_STRING,
    TYPE_BIT_NOT,
    TYPE_LOGIC_NOT,
    TYPE_INCOP,
    TYPE_MULOP,
    TYPE_ADDOP,
    TYPE_SHIFTOP,
    TYPE_INEQUAL_COMPOP,
    TYPE_EQUAL_COMPOP,
    TYPE_BIT_AND,
    TYPE_BIT_XOR,
    TYPE_BIT_OR,
    TYPE_LOGIC_AND,
    TYPE_LOGIC_OR,
    TYPE_CONDITIONOP_1,
    TYPE_CONDITIONOP_2,
    TYPE_ASSIGNOP,
    TYPE_LEFT_BRACE,
    TYPE_RIGHT_BRACE,
    TYPE_LEFT_PARENTHESIS,
    TYPE_RIGHT_PARENTHESIS,
    TYPE_LEFT_BRACKET,
    TYPE_RIGHT_BRACKET,
    TYPE_COLON,
    TYPE_SEMICOLON,
    TYPE_SINGLE_QUOTATION_MARK,
    TYPE_DOUBLE_QUOTATION_MARK,
    TYPE_COMMENT_START,
    TYPE_COMMENT_LINE,
    TYPE_COMMA,
    TYPE_DOT,
    TYPE_ARROW,
    TYPE_BACKSLASH,
    TYPE_PREPROCESS,
    NUMBER_OF_SYMBOL_TYPES
};

typedef struct
{
    char Name[TOKEN_LEN];
    int Id;
}   Keyword_T;

extern Symbol_T *Token0, *Token1;

extern int PutTokenToCache(Symbol_T *Token);
extern int OpType(char *Op);
extern int Scan();
extern int LexerInit();

#endif /* LEXER_H_ */
